using System;
using System.Collections.Generic;
using System.Text;

namespace SqlTools.DataAccessLibrary
{
	public enum ObjectState
	{
		New,
		Dirty,
		Delete,
		Deleted,
		None
	}

	public delegate void BusinessObjectEvent(object sender, BusinessObjectEventArgs e);

	public abstract class BusinessObject
	{
		protected ObjectState __objectState = ObjectState.New;
		protected string __connectionStringName = "";

		#region Events
		public event BusinessObjectEvent Loading;
		public event BusinessObjectEvent Loaded;
		public event BusinessObjectEvent Saving;
		public event BusinessObjectEvent Saved;
		public event BusinessObjectEvent Inserting;
		public event BusinessObjectEvent Inserted;
		public event BusinessObjectEvent Updating;
		public event BusinessObjectEvent Updated;
		public event BusinessObjectEvent Deleting;
		public event BusinessObjectEvent Deleted;
		#endregion

		public ObjectState _ObjectState
		{
			get { return __objectState; }
		}

		public string _ConnectionStringName
		{
			get { return __connectionStringName; }
			set
			{
				if ( string.IsNullOrEmpty(__connectionStringName) )
				{
					__connectionStringName = value;
				}
			}
		}

		protected void _UpdateState()
		{
			switch ( __objectState )
			{
				case ObjectState.New:
					break;
				case ObjectState.Dirty:
					break;
				case ObjectState.Delete:
					break;
				case ObjectState.None:
					__objectState = ObjectState.Dirty;
					break;
				case ObjectState.Deleted:
					break;
				default:
					__objectState = ObjectState.New;
					break;
			}
		}

		public void _UpdateState(ObjectState objectState)
		{
			__objectState = objectState;
		}

		#region Event Launchers
		protected virtual void OnLoading(BusinessObject obj)
		{
			if ( this.Loading != null )
				this.Loading(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnLoaded(BusinessObject obj)
		{
			if ( this.Loaded != null )
				this.Loaded(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnSaving(BusinessObject obj)
		{
			if ( this.Saving != null )
				this.Saving(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnSaved(BusinessObject obj)
		{
			if ( this.Saved != null )
				this.Saved(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnInserting(BusinessObject obj)
		{
			if ( this.Inserting != null )
				this.Inserting(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnInserted(BusinessObject obj)
		{
			if ( this.Inserted != null )
				this.Inserted(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnUpdating(BusinessObject obj)
		{
			if ( this.Updating != null )
				this.Updating(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnUpdated(BusinessObject obj)
		{
			if ( this.Updated != null )
				this.Updated(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnDeleting(BusinessObject obj)
		{
			if ( this.Deleting != null )
				this.Deleting(this, new BusinessObjectEventArgs(obj));
		}

		protected virtual void OnDeleted(BusinessObject obj)
		{
			if ( this.Deleted != null )
				this.Deleted(this, new BusinessObjectEventArgs(obj));
		}
		#endregion

		public virtual void MarkForDeletion()
		{
			MarkForDeletion(true);
		}

		public virtual void MarkForDeletion(bool delete)
		{
			__objectState = ObjectState.Delete;
		}

		public virtual void Save()
		{
			OnSaving(this);
			
			switch ( __objectState )
			{
				case ObjectState.New:
					Insert();
					break;
				case ObjectState.Dirty:
					Update();
					break;
				case ObjectState.Delete:
					Delete();
					break;
			}

			OnSaved(this);
		}

		public abstract void Update();

		public abstract void Insert();

		public abstract void Delete();
	}
}
